# Copyright (c) 2007, Enrico Franchi
# All rights reserved.
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
#
#     * Redistributions of source code must retain the above copyright
#       notice, this list of conditions and the following disclaimer.
#     * Redistributions in binary form must reproduce the above copyright
#       notice, this list of conditions and the following disclaimer in the
#       documentation and/or other materials provided with the distribution.
#     * Neither the name of the University of California, Berkeley nor the
#       names of its contributors may be used to endorse or promote products
#       derived from this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY
# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
# DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY
# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

import re
import itertools

import package
from package import PackageKey


class ParseError(Exception):
    pass
    
def parse_info(lines):       
    package_dict = {}
    if isinstance(lines, (str, unicode)):
        lines = lines.split('\n')
    parse_first_line(lines, package_dict)
    parse_homepage(lines, package_dict)
    parse_description(lines, package_dict)
    parse_rest(lines, package_dict)
    return package_dict

def parse_first_line(lines, d):
    rex = re.compile(r'(?P<name>\S+) (?P<version>\S+), (?P<revision>Revision \d+, |)(?P<directory>\S+/\S+)(?P<variants> \(Variants: .+\)|)')
    line = lines.pop(0)
    match = rex.match(line)
    if match:
        d.update(match.groupdict())
        if d.has_key(PackageKey.REVISION):
            d[PackageKey.REVISION] = d[PackageKey.REVISION][9:-2] # count the characters!
        if d.has_key(PackageKey.VARIANTS):
            d[PackageKey.VARIANTS] = d[PackageKey.VARIANTS][12:-1].split(', ')
    else: raise ParseError('First info line invalid')

def parse_homepage(lines, d):
    line = lines.pop(0)
    if len(line) == 0:
        lines.insert(0, line)
        d[PackageKey.HOMEPAGE] = ''
        return
    else:
        d[PackageKey.HOMEPAGE] = line

def parse_description(lines, d):
    line1 = lines.pop(0)
    if len(line1) == 0:
        description_lines = []
        last = 0
        for index, line in itertools.izip(itertools.count(), lines):
            if len(line) == 0:
                last = index
                break
            else:
                description_lines.append(line)
        del lines[0:last+1]
        d[PackageKey.DESCRIPTION] = '\n'.join(description_lines)
    else:
        lines.insert(0, line1)
        d[PackageKey.DESCRIPTION] =  ''

def parse_rest(lines, d):
    line = lines.pop(0)
    try:
        if line.startswith('Build Dependencies: '):
            d[PackageKey.BUILD_DEPENDENCIES] = line[20:].split(', ')
            line = lines.pop(0)
        else:
            d[PackageKey.BUILD_DEPENDENCIES] = []
        if line.startswith('Library Dependencies: '):
            d[PackageKey.LIBRARY_DEPENDENCIES] = line[22:].split(', ')
            line = lines.pop(0)
        else:
            d[PackageKey.LIBRARY_DEPENDENCIES] = []
        if line.startswith('Runtime Dependencies: '):
            d[PackageKey.RUNTIME_DEPENDENCIES] = line[22:].split(', ')
            line = lines.pop(0)
        else:
            d[PackageKey.RUNTIME_DEPENDENCIES] = []
        if line.startswith('Platforms: '):
            d[PackageKey.PLATFORMS] = line[11:].split(' ')
            line = lines.pop(0)
        else:
            d[PackageKey.PLATFORMS] = []
        if line.startswith('Maintainers: '):
            d[PackageKey.MAINTAINERS] = line[13:].split(' ')
            line = lines.pop(0)
        else:
            d[PackageKey.MAINTAINERS] = []    
        lines.insert(0, line)
    except IndexError:
        pass